package com.xiaobaibai.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaobaibai.entity.DistributionRecording;
import com.xiaobaibai.entity.DistributionUser;
import com.xiaobaibai.entity.User;
import com.xiaobaibai.response.ResponseFormat;
import com.xiaobaibai.service.IDistributionPayService;
import com.xiaobaibai.service.IDistributionRecordingService;
import com.xiaobaibai.service.IDistributionUserService;
import com.xiaobaibai.service.IUserService;
import com.xiaobaibai.units.SecurityUnit;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@Api(tags = "分销接口")
@RequestMapping("/distribution")
@CrossOrigin
@Slf4j
public class DistributionController {

    /**
     * 分销系统的功能
     * 1.分销主页
     * 2.开通分销商
     * 3.绑定上级分销商
     * 4.查看自己的下级们
     * 5.查看自己的金额增减记录(有分页,每页25条)
     * 6.申请提现(加锁!)
     */
    @Autowired
    private IDistributionPayService distributionPayService;

    @Autowired
    private IDistributionRecordingService distributionRecordingService;

    @Autowired
    private IDistributionUserService distributionUserService;

    @Autowired
    private IUserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/list")
    @ApiOperation("分销主页")
    public ResponseFormat list(){
        Integer userId = SecurityUnit.getUserId();
        QueryWrapper<DistributionUser> q1=new QueryWrapper<>();
        q1.eq("user_id",userId);
        DistributionUser distributionUser = distributionUserService.getOne(q1);
        if(distributionUser==null)
            return ResponseFormat.failure("未开通分销商");
        return ResponseFormat.ok("ok",distributionUser);
    }

    @PostMapping("/become")
    @ApiOperation("成为分销商")
    public ResponseFormat becomeBoss(@RequestBody @Validated DistributionUser distributionUser){

        Integer userId=SecurityUnit.getUserId();
        //不能重复成为
        QueryWrapper<DistributionUser> q1=new QueryWrapper<>();
        q1.eq("user_id",userId);
        DistributionUser one = distributionUserService.getOne(q1);
        if(one!=null)
            return ResponseFormat.failure("已是分销商");
        String code=this.createDistributionCode(userId);
        distributionUser.setUserId(userId);
        distributionUser.setInvitationCode(code);
        distributionUserService.save(distributionUser);//保存
        return ResponseFormat.ok("开通成功");
    }

    @GetMapping("/bindBoss")
    @ApiOperation("绑定上级分销商")
    public ResponseFormat bindBoss(@RequestParam(value = "code") String code){
        if(StringUtils.isBlank(code))
            return ResponseFormat.failure("邀请码错误");
        Integer userId=SecurityUnit.getUserId();
        QueryWrapper<DistributionUser> q1=new QueryWrapper<>();
        q1.select("id","superior_code","invitation_code");
        q1.eq("user_id",userId);
        DistributionUser distributionUser = distributionUserService.getOne(q1);
        /**
         * 成为分销商后才可以绑定上级
         */
        if(distributionUser==null)
            return ResponseFormat.failure("成为分销商后才可以绑定上级");
        if(distributionUser.getSuperiorCode()!=null)
            return ResponseFormat.failure("您已经绑定了上级");
        /**
         * 不可以相互绑定
         */
        QueryWrapper<DistributionUser> q2=new QueryWrapper<>();
        q2.select("id","superior_code");
        q2.eq("invitation_code",code);//查出上级用户的上级邀请码
        DistributionUser distributionUserParent = distributionUserService.getOne(q2);
        if(distributionUserParent==null)
            return ResponseFormat.failure("上级不存在");
        if(StringUtils.equals(distributionUserParent.getSuperiorCode(),distributionUser.getInvitationCode()))
            return ResponseFormat.failure("不可相互绑定");
        UpdateWrapper<DistributionUser> u1=new UpdateWrapper<>();
        u1.eq("user_id",userId);
        u1.set("superior_code",code);
        distributionUserService.update(u1);//绑定
        return ResponseFormat.ok("绑定成功");
    }

    @GetMapping("/getSubordinates")
    @ApiOperation("查看自己的下级们")
    public ResponseFormat getSubordinates(){
        Integer userId=SecurityUnit.getUserId();
        List<Integer> userIdList = distributionUserService.getSubordinates(userId);
        if(userIdList==null||userIdList.size()==0)
            return ResponseFormat.ok("无下级");
        QueryWrapper<User> q1=new QueryWrapper<>();
        q1.select("user_name","user_image");
        q1.in("user_id",userIdList);
        List<User> list = userService.list(q1);
        return ResponseFormat.ok("ok",list);
    }

    @GetMapping("/recording")
    @ApiOperation("查看自己的金额增减记录")
    public ResponseFormat lookRecording(@RequestParam(value = "pageNum")Integer pageNum){
        Integer userId=SecurityUnit.getUserId();
        QueryWrapper<DistributionUser> q0=new QueryWrapper<>();
        q0.select("id");
        q0.eq("user_id",userId);
        DistributionUser distributionUser = distributionUserService.getOne(q0);
        List<DistributionRecording> list =
                distributionRecordingService.lookRecording(distributionUser.getId(), pageNum, 25);
        return ResponseFormat.ok("ok",list);
    }

    @GetMapping("/applicationPay")
    @ApiOperation("申请提现")
    public ResponseFormat applicationPay(@RequestParam(value = "amount") Double amountStr){
        /**
         * 1.先检查日期是否为25号以后
         * 2.上锁
         * 3.参数是否大于0,转为两位小数
         * 4.是否有这么多钱
         * //事务开始
         * 5.提现申请
         * 6.记录提现
         * 7.减去余额
         * //事务结束
         */
        int dayOfMonth = LocalDate.now().getDayOfMonth();
        if(dayOfMonth<25)
            return ResponseFormat.failure("提现日未到");
        Integer userId=SecurityUnit.getUserId();
        Boolean flag = stringRedisTemplate.hasKey("distributionLock:" + userId);
        if(flag)//有此锁
            return ResponseFormat.failure("操作频繁");
        stringRedisTemplate.opsForValue().set("distributionLock:"+userId,"1",30, TimeUnit.SECONDS);

        BigDecimal amount=new BigDecimal(amountStr);

        BigDecimal decimal = amount.setScale(2, RoundingMode.HALF_UP);//四舍五入,保留两位小数
        QueryWrapper<DistributionUser> q1=new QueryWrapper<>();
        q1.select("id","amount");
        q1.eq("user_id",userId);
        DistributionUser distributionUser = distributionUserService.getOne(q1);
        if(decimal.compareTo(distributionUser.getAmount())<0)
            return ResponseFormat.failure("余额不足");

        //正式开始提现
        try {
            distributionPayService.applicationPay(userId,amount,distributionUser.getId());
        }catch (Exception e){
            log.error(e.getMessage());
            return ResponseFormat.failure("系统繁忙");
        }

        return ResponseFormat.ok("已申请,近几天到账");
    }

    private String createDistributionCode(Integer userId){
        //生成分销商邀请码
        userId=userId*11;
        String s = RandomStringUtils.randomAlphanumeric(4);//随机生成字母数字
        return s+userId;
    }

}
